﻿using LardonPokerSimulator.Model.Deck;
using LardonPokerSimulator.Model.Observers;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace LardonPokerSimulator.Model
{
    public class Player : Subject
    {
        private static int playerID = 0;
        private static readonly short MAX_PLAYER = 10;
        private static readonly short MIN_PLAYER = 2;

        private static Random __tokenRandom = new Random();
        private uint _tokens = 0;
        private Hand _playersHand = null;
        private PlayerStatus _playerStatus = PlayerStatus.Active;
        private String _name = String.Empty;

        private Point _pointPlayer;

        public Player(String aName)
        {
            this._name = aName;

            this._playersHand = new Hand(this);

            //Random token number
            int tokenRand = Player.__tokenRandom.Next(5, 101);
            this._tokens = (uint)(tokenRand * 1000);

            #region Player Position
            switch (playerID)
            {
                case 0:
                    _pointPlayer = new Point(175, 25);
                    break;
                case 1:
                    _pointPlayer = new Point(375, 25);
                    break;
                case 2:
                    _pointPlayer = new Point(575, 25);
                    break;
                case 3:
                    _pointPlayer = new Point(725, 175);
                    break;
                case 4:
                    _pointPlayer = new Point(725, 275);
                    break;
                case 5:
                    _pointPlayer = new Point(575, 425);
                    break;
                case 6:
                    _pointPlayer = new Point(375, 425);
                    break;
                case 7:
                    _pointPlayer = new Point(175, 425);
                    break;
                case 8:
                    _pointPlayer = new Point(25, 275);
                    break;
                case 9:
                    _pointPlayer = new Point(25, 175);
                    break;
                default:
                    throw new Exception("Player ID overflow");
            }
            #endregion

            playerID++;

            this.Attach(LardonPokerSimulator.Controller.ControllerLPS.LARDON_FORM);
        }

        #region Properties
        public String Name
        {
            get { return this._name; }
        }

        public uint Tokens
        {
            get { return this._tokens; }
        }

        

        #endregion

        #region Methods
        public void AddToken(uint aNbTokenAdd)
        {
            this._tokens += aNbTokenAdd;
            base.NotifyObservers();
        }

        public void SubstractToken(uint aNbTokenSub)
        {
            this._tokens -= aNbTokenSub;
            base.NotifyObservers();
        }

        public void ChangeStatus(PlayerStatus aNewPlayerStatus)
        {
            this._playerStatus = aNewPlayerStatus;
            base.NotifyObservers();
        }

        public void Draw(Graphics aGraphics)
        {
            SolidBrush brushPlayer = new SolidBrush(Color.Green);

            if (this._playerStatus == PlayerStatus.Out)
            {
                brushPlayer = new SolidBrush(Color.Red);
            }
            else if (this._playerStatus == PlayerStatus.SmallBling)
            {
                brushPlayer = new SolidBrush(Color.Orange);
            }
            else if (this._playerStatus == PlayerStatus.BigBlind)
            {
                brushPlayer = new SolidBrush(Color.Yellow);
            }

            SolidBrush burshPlayerName = new SolidBrush(Color.Black);

            Rectangle rectPlayer = new Rectangle(this._pointPlayer.X, this._pointPlayer.Y, 50, 50);
            aGraphics.FillRectangle(brushPlayer, rectPlayer);
            Pen pen = new Pen(Color.Black, 2);
            aGraphics.DrawRectangle(pen, rectPlayer);

            Font font = new System.Drawing.Font("Arial", 10.0f);
            aGraphics.DrawString(this._name, font, burshPlayerName, new PointF(this._pointPlayer.X + 15, this._pointPlayer.Y + 15));


            Console.WriteLine("{0} : X: {1} Y: {2}", this._name, this._pointPlayer.X, this._pointPlayer.Y);
        }

        #endregion

        #region Overrides
        public override string ToString()
        {
            StringBuilder stringBuilderCard = new StringBuilder("Name: ").Append(this._name).AppendLine();

            foreach (Card c in this._playersHand.HandsCards)
            {
                stringBuilderCard.Append(c.ToString()).AppendLine();
            }

            stringBuilderCard.Append("Tokens: ").Append(this._tokens).AppendLine();

            return stringBuilderCard.ToString();
        }
        #endregion

        #region Statics

        public static Player[] GenerateRandomPlayers()
        {
            Random rand = new Random();

            int nbPlayer = rand.Next(MIN_PLAYER, MAX_PLAYER);
            List<Player> randomCreatedPlayers = new List<Player>();

            Player rob = new Player("Rob");
            randomCreatedPlayers.Add(rob);

            for (int i = 1; i < nbPlayer; i++)
            {
                Player p = new Player(String.Format("P{0}", i + 1));
                randomCreatedPlayers.Add(p);
            }

            return randomCreatedPlayers.ToArray();
        }

        #endregion
    }

    public enum PlayerStatus
    {
        Active = 0,
        Out = 1,
        BigBlind = 2,
        SmallBling = 3,
        TheButton = 4
    }
}
